package com.basic.common.aspect;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.basic.common.annotation.DictParam;
import com.basic.config.DictConfig;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Map;

@Slf4j
@Aspect
@Component
public class DictAspect {

    public static final String GET = "get";

    public static final String SET = "set";

    @Pointcut("@annotation(com.basic.common.annotation.DictParam)")
    private void dictHelper() {
    }

    @Around("dictHelper()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        try {
            // 执行方法得到结果
            Object result = joinPoint.proceed();
            //检查允许的字典项
            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
            if (method.isAnnotationPresent(DictParam.class)) {
                DictParam dictParam = method.getAnnotation(DictParam.class);
                String oldDictType = dictParam.dictType();
                String oldField = dictParam.field();
                String oldTargetField = dictParam.targetField();
                // 字典转换开始（使用反射）
                Class<?> clazz = result.getClass();
                // 反射调用get方法获取字段值
                Method sourceMethod = clazz.getMethod(GET + firstToUppercase(oldField));
                Object fieldValue = sourceMethod.invoke(result);
                if(ObjectUtil.isNull(fieldValue)){
                    return result;
                }
                // 获取字典值
                Map<String, String> dictVoMap = DictConfig.DICT_MAPPER.get(oldDictType);
                if(dictVoMap.isEmpty()){
                    return result;
                }
                String dictName = dictVoMap.get(fieldValue.toString());
                // 获取目标方法进行设值
                String targetField = StrUtil.isBlank(oldTargetField) ? oldField : oldTargetField;
                Method targetMethod = clazz.getMethod(SET + firstToUppercase(targetField), dictName.getClass());
                targetMethod.invoke(result, dictName);
            }
            return result;
        } catch (Throwable throwable) {
            log.error("error:", throwable);
            return null;
        }
    }

    private String firstToUppercase(String str) {
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }
}
